/*- coding = utf-8 -*-
@Time : 2023/7/10 14:25
@Author : 管茂良
@File : useFunc.ts
@web  : www.php-china.com
@Software: WebStorm
*/
import {ExtractPropTypes, onMounted, ref, VNode} from "vue";
import {videoConfigInit} from "../config/index";

interface videoConfigInterface{
    videoConfig:{
        src:string
        poster:string
        volume?:number
        themeColor?:string
        activeColor?:string
        width?:string
        height?:string
    }
}
export const useFunc = (props: Prettify<Readonly<ExtractPropTypes<{ videoConfig: videoConfigInterface }>>>) =>{
    // 视频配置
    let videoConfig = ref({
        src:props.videoConfig.src!=""?props.videoConfig.src:videoConfigInit.src, //视频
        poster: props.videoConfig.poster!=""?props.videoConfig.poster:videoConfigInit.poster, // 初始化占位图片
        volume: props.videoConfig.volume??videoConfigInit.volume,
        themeColor:props.videoConfig.themeColor??videoConfigInit.themeColor,//主体颜色
        activeColor:props.videoConfig.activeColor??videoConfigInit.activeColor,//选中颜色
        width:props.videoConfig.width??videoConfigInit.width,
        height:props.videoConfig.height??videoConfigInit.height,
    })

    //视频状态
    let videoState = ref({
        play: false, //播放状态
        hideControl: true, // 控制栏状态
        distance: 0, // 移动的距离
        downState: false, // 鼠标点击进度条
        playState: false,
        leftInit: 0, // 当前进度初始偏移量
        isFullScreen: false,//是否全屏
        isHalfScreen: false,//是否半屏
        isLoading:false,//是否加载
    })
    //声音状态
    let voiceState = ref({ // 同上
        distance: 0,
        downState: false,
        topInit: 0
    })
    let videoRef = ref(null) // video
    let videoDomRef = ref<any>(null) // video
    let videoProOutRef = ref(null) // 视频总进度条
    let videoCacheRef = ref(null) // 视频缓存
    let videoProRef = ref(null) // 视频进度条
    let videoPoiRef = ref(null) // 视频进度点
    let duration = ref<string>("") // 视频总时长
    let currentTime = ref<string>("") // 视频当前播放时长
    let processWidth = ref(0) // 视频进度条总长度
    let voiceProOutRef = ref(null) // 音频总进度条
    let voiceProRef = ref(null) // 音频进度条
    let voicePoiRef = ref(null) // 音频进度点
    let voiceProcessHeight = ref(0)//声音进度高度

    let enterVoiceTime = ref<any>(null)
    //鼠标移入控件
    const handleMouseEnterControlVoice = (controlName:string)=>{
        enterVoiceTime.value?clearTimeout(enterVoiceTime.value):"";
        let voiceIcon = document.querySelector(`.${controlName}`)
        voiceIcon.className = `control-fade-enter-active show display-show-style ${controlName}`
    }
    //鼠标移出控件
    const handleMouseLeaveControlVoice = (controlName:string)=>{
        let voiceIcon = document.querySelector(`.${controlName}`)
        voiceIcon.className = `control-fade-leave-active hide ${controlName}`
        enterVoiceTime.value = setTimeout(()=>{
            voiceIcon.className = `control-fade-leave-active hide display-hide-style ${controlName}`
        },1000)
    }
    const handleLoadedmetadata = (e)=>{
        //获取视频总时长
        duration.value = timeTranslate(videoDomRef.value.duration)
    }
    //监听视频播放过程中的时间
    const handleTimeupdate = ()=>{
        const percentage = 100 * videoDomRef.value.currentTime / videoDomRef.value.duration
        videoProRef.value.style.width = percentage + '%'
        videoPoiRef.value.style.left = percentage - 1 + '%'
        currentTime.value = timeTranslate(videoDomRef.value.currentTime)
    }
    //监听结束播放事件
    const handleEnded = (e)=>{
        videoProRef.value.style.width = 0
        videoPoiRef.value.style.left = 0
        currentTime.value = "0"
        videoState.value.play = false
        videoState.value.hideControl = false
    }
    //监听声音修改
    const handleVolumechange = ()=>{
        //调整声音滚动样式
        const percentage =  (videoDomRef.value.volume-0.05) * 100
        voiceProRef.value.style.height = percentage.toFixed(0) + '%'
        voicePoiRef.value.style.bottom = percentage.toFixed(0) + '%'
    }
    //获取视频缓存长度
    const handleVideoBufferLength = ()=>{
        let duration = videoDomRef.value.duration; // 视频总长度
        if (duration > 0) {
            for (let i = 0; i < videoDomRef.value.buffered.length; i++) {
                // 寻找当前时间之后最近的点
                if (videoDomRef.value.buffered.start(videoDomRef.value.buffered.length - 1 - i) < videoDomRef.value.currentTime) {
                    let bufferedLength = (videoDomRef.value.buffered.end(videoDomRef.value.buffered.length - 1 - i) / duration) * 100 +
                        "%";
                    videoCacheRef.value.style.width = bufferedLength
                    break;
                }
            }
        }
    }

    const handleInitVideo = ()=> { // 初始化video相关事件

        // 1、loadstart：视频查找。当浏览器开始寻找指定的音频/视频时触发，也就是当加载过程开始时
        videoDomRef.value.addEventListener('loadstart', function(e) {
            console.log('提示视频的元数据已加载')

        })

        // 2、durationchange：时长变化。当指定的音频/视频的时长数据发生变化时触发，加载后，时长由 NaN 变为音频/视频的实际时长
        videoDomRef.value.addEventListener('durationchange', handleLoadedmetadata)

        // 3、loadedmetadata ：元数据加载。当指定的音频/视频的元数据已加载时触发，元数据包括：时长、尺寸（仅视频）以及文本轨道
        videoDomRef.value.addEventListener('loadedmetadata', function(e) {
            console.log('提示视频的元数据已加载')
            console.log(e)
        })

        // 4、loadeddata：视频下载监听。当当前帧的数据已加载，但没有足够的数据来播放指定音频/视频的下一帧时触发
        videoDomRef.value.addEventListener('loadeddata', function(e) {
            // console.log('提示当前帧的数据是可用的')
            // console.log(e)
        })

        // 5、progress：浏览器下载监听。当浏览器正在下载指定的音频/视频时触发
        videoDomRef.value.addEventListener('progress', function(e) {
            // console.log('提示视频正在下载中')
            // console.log(e)
            handleVideoBufferLength()
        })

        // 6、canplay：可播放监听。当浏览器能够开始播放指定的音频/视频时触发
        videoDomRef.value.addEventListener('canplay', function(e) {
            console.log('提示该视频已准备好开始播放')
            console.log(e)
            videoState.value.isLoading = false;
        })

        // 7、canplaythrough：可流畅播放。当浏览器预计能够在不停下来进行缓冲的情况下持续播放指定的音频/视频时触发
        videoDomRef.value.addEventListener('canplaythrough', function(e) {
            console.log('提示视频能够不停顿地一直播放')
            console.log(e)
        })

        // 8、play：播放监听
        videoDomRef.value.addEventListener('play', function(e) {
            console.log('提示该视频正在播放中')
            console.log(e)
        })

        // 9、pause：暂停监听
        videoDomRef.value.addEventListener('pause', function(e) {
            console.log('暂停播放')
            console.log(e)
        })

        // 10、seeking：查找开始。当用户开始移动/跳跃到音频/视频中新的位置时触发
        videoDomRef.value.addEventListener('seeking', handleTimeupdate)

        // 11、seeked：查找结束。当用户已经移动/跳跃到视频中新的位置时触发
        videoDomRef.value.addEventListener('seeked', function(e) {
            console.log('进度条已经移动到了新的位置')
            console.log(e)
            videoState.value.isLoading = false
        })

        // 12、waiting：视频加载等待。当视频由于需要缓冲下一帧而停止，等待时触发
        videoDomRef.value.addEventListener('waiting', function(e) {
            videoState.value.isLoading = true;
            console.log('视频加载等待')
            console.log(e)
        })

        // 13、playing：当视频在已因缓冲而暂停或停止后已就绪时触发
        videoDomRef.value.addEventListener('playing', function(e) {
            videoState.value.isLoading = false;
            console.log('playing')
            console.log(e)
        })

        // 14、timeupdate：目前的播放位置已更改时，播放时间更新
        videoDomRef.value.addEventListener('timeupdate',handleTimeupdate)

        // 15、ended：播放结束
        videoDomRef.value.addEventListener('ended',handleEnded)

        // 16、error：播放错误
        videoDomRef.value.addEventListener('error', function(e) {
            console.log('视频出错了')
            console.log(e)
        })

        // 17、volumechange：当音量更改时
        videoDomRef.value.addEventListener('volumechange', handleVolumechange)

        // 18、stalled：当浏览器尝试获取媒体数据，但数据不可用时
        videoDomRef.value.addEventListener('stalled', function(e) {
            console.log('stalled')
            console.log(e)
        })

        // 19、ratechange：当视频的播放速度已更改时
        videoDomRef.value.addEventListener('ratechange', function(e) {
            console.log('ratechange')
            console.log(e)
        })


        videoDomRef.value.addEventListener("click", () => { // 点击视频区域可以进行播放或者暂停
            console.log("点击视频区域可以进行播放或者暂停");
            if(videoDomRef.value.paused || videoDomRef.value.ended) {
                if(videoDomRef.value.ended) {
                    videoDomRef.value.currentTime = "0"
                }
                play('btn')
            } else {
                pause('btn')
            }
        })
    }
    const play = (flag?:any) => { // 播放按钮事件
        if(flag) videoState.value.playState = true
        videoState.value.play = true
        videoDomRef.value.play()
    }
    const pause = (flag?:any) => { // 暂停按钮事件
        if(flag) videoState.value.playState = false
        videoDomRef.value.pause()
        videoState.value.play = false
    }
    //点击后，判断视频是否加载完成
    const handleProgressDown = (ev) => { // 监听点击进度条事件，方便获取初始点击的位置
        //如果数据初始化失败，需要重新获取
        handleInitData()
        // 视频暂停
        videoState.value.downState = true //按下鼠标标志
        pause()
        videoState.value.distance = ev.clientX - videoState.value.leftInit
    }
    // 监听移动进度条事件，同步播放相关事件
    const handleProgressMove = (ev) => {
        if(!videoState.value.downState) return
        let disX = ev.clientX - videoState.value.leftInit
        if(disX > processWidth.value) {
            disX = processWidth.value
        }
        if(disX < 0) {
            disX = 0
        }
        videoState.value.distance = disX
        videoDomRef.value.currentTime = videoState.value.distance / processWidth.value * videoDomRef.value.duration
    }
    //松开鼠标，播放当前进度条视频
    const handleProgressUp = () => {
        videoState.value.downState = false
        // 视频播放
        videoDomRef.value.currentTime = videoState.value.distance / processWidth.value * videoDomRef.value.duration
        currentTime.value = timeTranslate(videoDomRef.value.currentTime)
        if(videoState.value.playState) {
            play()
        }
    }
    const handleVolProgressDown = (ev) => { // 监听声音点击事件
        voiceState.value.topInit = getOffset(voiceProOutRef.value).top
        voiceProcessHeight.value = voiceProOutRef.value.clientHeight
        voiceState.value.downState = true //按下鼠标标志
        console.log(voiceProcessHeight.value - (ev.clientY - voiceState.value.topInit),"111111");
        voiceState.value.distance = voiceProcessHeight.value-(ev.clientY - voiceState.value.topInit)
    }
    const handleVolProgressMove = (ev) => { // 监听声音进度条移动事件
        if(!voiceState.value.downState) return
        let disY = voiceState.value.topInit + voiceProcessHeight.value - ev.clientY
        if(disY > voiceProcessHeight.value) {
            disY = voiceProcessHeight.value
        }
        if(disY < 0) {
            disY = 0
        }
        console.log(disY,"2222222222222");
        voiceState.value.distance = disY
        //通过(滚动偏离长度)除于(滚动总高度)
        videoDomRef.value.volume = voiceState.value.distance / voiceProcessHeight.value>1?1:voiceState.value.distance / voiceProcessHeight.value
        videoConfig.value.volume = Math.round(videoDomRef.value.volume * 100)
    }
    const handleVolProgressUp = (e:Event)=>{ // 监听声音鼠标离开事件
        e.stopPropagation();
        voiceState.value.downState = false //按下鼠标标志
        videoDomRef.value.volume = voiceState.value.distance / voiceProcessHeight.value>1?1:voiceState.value.distance / voiceProcessHeight.value
        videoConfig.value.volume = Math.round(videoDomRef.value.volume * 100)
    }
    const handleClickVoice = (e:Event)=>{ // 点击声音控件
        e.stopPropagation()
        if(videoDomRef.value.volume*100>0 && videoDomRef.value.volume*100<=100){
            videoDomRef.value.volume = 0;
        }else{
            videoDomRef.value.volume = 1;
        }
        videoConfig.value.volume = Math.round(videoDomRef.value.volume * 100)
        voiceState.value.distance = Math.round(videoDomRef.value.volume * 100)
    }
    const handleControls = (ev, flag) => { // 监听离开或者进入视频区域隐藏或者展示控制栏
        switch (flag) {
            case 'start':
                videoState.value.hideControl = false
                break;
            case 'end':
                videoState.value.hideControl = true
                break;
            default:
                break;
        }
    }
    //全屏操作
    const handleScreen = () => {
        videoState.value.isFullScreen = !videoState.value.isFullScreen
        if(videoState.value.isFullScreen) {
            fullScreen()
        } else {
            exitFullscreen()
        }
    }
    //半屏操作
    const handleHalfScreen = () => {
        let halfHeight = (document.body.offsetHeight/2).toFixed(0)
        let halfWidth = (document.body.offsetWidth/2).toFixed(0)
        videoState.value.isHalfScreen = !videoState.value.isHalfScreen
        if(videoState.value.isHalfScreen){
            videoRef.value.style.width = halfWidth+"px"
            videoRef.value.style.height = halfHeight+"px"
        }else{
            videoRef.value.style.width = videoConfig.value.width
            videoRef.value.style.height = videoConfig.value.height
        }
    }
    const timeTranslate = (t):string => { // 时间转化
        let m = Math.floor(t / 60)
        m < 10 && (m = '0' + m)
        return m + ":" + (t % 60 / 100 ).toFixed(2).slice(-2)
    }
    const getOffset = (node:any, offset?:any) => { // 获取当前屏幕下进度条的左偏移量和又偏移量
        if(!offset) {
            offset = {}
            offset.left = 0
            offset.top = 0
        }
        if(node === document.body || node === null) {
            return offset
        }
        offset.top += node.offsetTop
        offset.left += node.offsetLeft
        return getOffset(node.offsetParent, offset)
    }
    const fullScreen = () => {
        let ele = document.documentElement
        if (ele.requestFullscreen) {
            ele.requestFullscreen()
        } else if (ele.mozRequestFullScreen) {
            ele.mozRequestFullScreen()
        } else if (ele.webkitRequestFullScreen) {
            ele.webkitRequestFullScreen()
        }
        videoRef.value.style.width = "100%"
        videoRef.value.style.height = "100%"
    }
    const exitFullscreen =()=> {
        let de = document
        if (de.exitFullscreen) {
            de.exitFullscreen();
        } else if (de.mozCancelFullScreen) {
            de.mozCancelFullScreen();
        } else if (de.webkitCancelFullScreen) {
            de.webkitCancelFullScreen();
        }
        videoRef.value.style.width = videoConfig.value.width
        videoRef.value.style.height = videoConfig.value.height
    }
    //初始化数据
    const handleInitData = ()=>{
        //视频进度条总长度
        if(processWidth.value<=0){
            processWidth.value = videoProOutRef.value.clientWidth
        }
        // 设置播放长度
        if(videoState.value.leftInit<=0){
            videoState.value.leftInit = getOffset(videoProOutRef.value).left
        }
        // 设置初始化声音
        videoDomRef.value.volume=videoConfig.value?.volume / 100
    }
    onMounted(()=>{
        handleInitData()
        handleInitVideo()
    })
    return {
        videoConfig,videoState,voiceState,videoRef,videoDomRef,videoProOutRef,videoCacheRef,videoProRef,videoPoiRef,duration,currentTime,
        processWidth,voiceProOutRef,voiceProRef,voicePoiRef,voiceProcessHeight,handleHalfScreen,handleMouseEnterControlVoice,handleMouseLeaveControlVoice,
        handleProgressDown,handleInitVideo,play,pause,handleProgressMove,handleProgressUp,handleVolProgressDown,handleVolProgressMove,handleClickVoice,
        handleVolProgressUp,handleControls,handleScreen,timeTranslate,getOffset,fullScreen,exitFullscreen
    }
}
